package com.test.hand.server;

import com.test.hand.protocol.MessageCodecSharable;
import com.test.hand.protocol.ProtocolFrameDecoder;
import com.test.hand.server.handler.ChatRequestHandler;
import com.test.hand.server.handler.LoginRequestMessageHandler;
import com.test.hand.server.handler.group.GroupChatRequestMessageHandler;
import com.test.hand.server.handler.group.GroupCreateRequestMessageHandler;
import com.test.hand.server.handler.group.GroupJoinRequestMessageHandler;
import com.test.hand.server.handler.group.GroupMembersRequestMessageHandler;
import com.test.hand.server.handler.quit.QuitHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ChatServer {
    public static void main(String[] args) throws InterruptedException {
        MessageCodecSharable MESSAGE_CODEC = new MessageCodecSharable();
        LoggingHandler LOGGING_HANDLER = new LoggingHandler(LogLevel.INFO);
        LoginRequestMessageHandler LOGIN_REQUEST_HANDLER = new LoginRequestMessageHandler(); // 登录请求逻辑处理
        ChatRequestHandler CHAT_REQUEST_HANDLER = new ChatRequestHandler();// 处理接受信息，处理ChatRequestMessage
        GroupCreateRequestMessageHandler GROUP_CREATE_HANDLER = new GroupCreateRequestMessageHandler();
        GroupChatRequestMessageHandler GROUP_CHAT_HANDLER = new GroupChatRequestMessageHandler();
        GroupJoinRequestMessageHandler GROUP_JOIN_HANDLER = new GroupJoinRequestMessageHandler();
        GroupMembersRequestMessageHandler GROUP_MEMBERS_HANDLER = new GroupMembersRequestMessageHandler();
        QuitHandler QUIT_HANDLER = new QuitHandler();


        // 搭建Server
        NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(boosGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        // 帧解码器
                        ch.pipeline().addLast(new ProtocolFrameDecoder());
                        // 协议解码器
                        ch.pipeline().addLast(LOGGING_HANDLER);
                        ch.pipeline().addLast(MESSAGE_CODEC);
                        // 5s服务端未向server发送数据的检测
                        ch.pipeline().addLast(
                                // 设置一个检测器，关注读事件，如果一个channel没有写东西，服务端就没有读取到东西
                                new IdleStateHandler(5, 0, 0));
                        // 添加双向处理器，处理检测器触发的事件
                        ch.pipeline().addLast(new ChannelDuplexHandler() {
                            @Override
                            public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
                                if (evt instanceof IdleStateEvent) {
                                    IdleStateEvent event = (IdleStateEvent) evt;
                                    // 如果client过久没有操作--断开连接
                                    if (event.state() == IdleState.READER_IDLE) {
                                        ctx.channel().close();
                                        log.debug("用户已经5s没有进行操作");
                                    }
                                }
                            }
                        });
                        // 实现登录响应逻辑
                        ch.pipeline().addLast(LOGIN_REQUEST_HANDLER);
                        // 处理接受信息，处理ChatRequestMessage
                        ch.pipeline().addLast(CHAT_REQUEST_HANDLER);
                        // 创建群组
                        ch.pipeline().addLast(GROUP_CREATE_HANDLER);
                        ch.pipeline().addLast(GROUP_CHAT_HANDLER);
                        ch.pipeline().addLast(GROUP_JOIN_HANDLER);
                        ch.pipeline().addLast(GROUP_MEMBERS_HANDLER);
                        ch.pipeline().addLast(QUIT_HANDLER);
                    }
                });
        // 可以试试syncUninterruptibly
        Channel channel = bootstrap.bind(8080).sync().channel();
        channel.closeFuture().sync();
    }

}
